package mvc.model

import app.AppContext
import com.hontech.pizzav2.R
import ext.*
import manager.AppManager
import org.json.JSONObject


class Status(val byteArray: ByteArray) {
    companion object {
        val MOTOR_STATUS_LIST = arrayOf("ok", "timeOut", "locked")
        val SENSOR_STATUS_LIST = arrayOf("normal", "abnormal")

        const val OK = 0x00
        const val TIME_OUT = 0x01
        const val LOCKED = 0x02

        private var fridgeTempMinValue = 0 // 温度控制最小值
        private var fridgeTempMaxValue = 0 // 温度控制最大值
        private var fridgeTempTimeOut = Int.MAX_VALUE / 2 // 超时时间
        private var fridgeErrorCount = 0 // 温度异常计数
        val APPEND_TIME_OUT = 1800
        var appendTimeOut = 0

        fun setFridgeTemp(tempValue: TempValue) {
            fridgeErrorCount = 0
            fridgeTempTimeOut = tempValue.timeOut * 60
            fridgeTempMaxValue = tempValue.max
            fridgeTempMinValue = tempValue.min
        }

        private fun refreshFaultError(status: Status) {
            val value = status.fridgeTempValue()

            if (((value < fridgeTempMinValue) || (value > fridgeTempMaxValue))) // 温度异常
            {
                if (!status.isFridgeOpen()) // 大门关闭 开始计数
                {
                    fridgeErrorCount++
                } else // 大门打开计数清零
                {
                    fridgeErrorCount = 0
                }
            } else // 温度正常
            {
                status.tempValueError = false
                fridgeErrorCount = 0
                appendTimeOut = 0
            }

            if ((fridgeErrorCount * 5) > (fridgeTempTimeOut + appendTimeOut)) {
                status.tempValueError = true
            }
            status.trouble()
            log("minValue:$fridgeTempMinValue-maxValue:$fridgeTempMaxValue-timeOut:$fridgeTempTimeOut-count:$fridgeErrorCount")
        }

        fun statusWithNormal(): Status {
            val arr = ByteArray(23) { 0x00 }
            return Status(arr)
        }
    }

    val innerPushMotor = byteArray.arg(1) // 内推货电机
    val heatDoorMotor = byteArray.arg(2) // 保温门电机
    val externPushMotor = byteArray.arg(3) // 外推货电机
    val externUpDownMotor = byteArray.arg(4) // 外升降电机
    val pickDoorMotor = byteArray.arg(5) // 取物门电机
    val rotationMotor = byteArray.arg(6) // 旋转步进电机
    val innerUpDownMotor = byteArray.arg(7) //内升降电机
    val tempSensor = byteArray.arg(8) // 温度传感器状态

    private val fridgeTempValueRaw = byteArray.argShort(9) // 冰箱温度
    val positionSwitch = byteArray.argInt(11)
    val positionSwitch2 = byteArray.arg(15)
    val positionSwitch3 = byteArray.arg(16)
    val ovenTempValue = byteArray.argShort(17)
    var ps = 0 // 位置开关异常信息

    var tempValueError = false // 温度异常
    var isFault = false // 是否故障
    var faultMessage = "" // 故障信息
    private var zt = "normal"

    fun queryStatus(): String {
        val motors = arrayOf(
            innerPushMotor,
            heatDoorMotor,
            externPushMotor,
            externUpDownMotor,
            pickDoorMotor,
            rotationMotor,
            innerUpDownMotor
        )

        val sb = StringBuilder()
        val keys = AppContext.resources.getStringArray(R.array.status_key)
        val values = AppContext.resources.getStringArray(R.array.status_val)
        for (i in 0 until 7) {
            sb.append(keys[i]).append(":").append(values[motors[i]]).append("\r\n")
        }
        sb.append(keys[7]).append(":") // 微波状态
        if (!isWaveError()) {
            sb.append("normal").append("\r\n")
        } else {
            sb.append("reveal").append("\r\n")
        }
        sb.append(keys[8]).append(":") // 大门状态
        if (isFridgeOpen()) {
            sb.append("open").append("\r\n")
        } else {
            sb.append("closed").append("\r\n")
        }
        sb.append(keys[9]).append(":") // 小门状态
        if (isGateOpen()) {
            sb.append("open").append("\r\n")
        } else {
            sb.append("closed").append("\r\n")
        }
        sb.append(keys[10]).append(":") // 光栅
        if (isRasterError()) {
            sb.append("blocked").append("\r\n")
        } else {
            sb.append("normal").append("\r\n")
        }
        sb.append(keys[11]).append(":") // 红外状态
        if (isIrdaError()) {
            sb.append("abnormal").append("\r\n")
        } else {
            sb.append("normal").append("\r\n")
        }
        sb.append(keys[12]).append(":") // 温度传感器状态
        if (tempSensor == 0x00) {
            sb.append("normal").append("\r\n")
        } else {
            sb.append("abnormal").append("\r\n")
        }
        sb.append("ps value:")
        sb.append(ps.toHex())
        return sb.toString()
    }

    fun fridgeTempValue(): Float {
        val tmp = fridgeTempValueRaw and 0xFFF
        return if ((tmp and 0x800) != 0x00) {
            val c = 0x1000 - tmp
            -c * 0.0625f
        } else {
            tmp * 0.0625f
        }
    }

    init {
        if (byteArray.size >= 28) {
            AppManager.McuSoftVersion = byteArray.argInt(19)
            ps = byteArray.arg(23) and 0x7F
            log("版本:${AppManager.McuSoftVersion.toHex()}")
        }

        if (byteArray.size >= 33) {
            val heatStatus = byteArray.arg(24)
            val time_count = byteArray.argInt(25)
            log("加热状态:$heatStatus 加热超时计数:$time_count")
        }

        refreshFaultError(this)
    }

    fun isFridgeOpen() = ((positionSwitch2 and 0x01) != 0x00) // 大门是否打开
    fun isGateOpen() = ((positionSwitch2 and 0x02) != 0x00) // 小门是否打开
    fun isReplenishButtonClicked() = ((positionSwitch2 and 0x04) == 0x0) // 补货按钮是否被按下
    fun isRasterError() = ((positionSwitch2 and 0x08) == 0x00) // 光栅被遮挡
    fun isIrdaError() = ((positionSwitch2 and 0x10) == 0x00) // 红外异常
    fun isRotationTrough() = ((positionSwitch2 and 0x20) != 0x00) // 旋转槽型开关被遮挡
    fun isInnerPushTrough() = ((positionSwitch2 and 0x40) != 0x00) // 内推货槽型开关

    fun isWaveError() = ((positionSwitch3 and 0x01) != 0x00) // 微波泄露
    fun isInnerUpDownTrough() = ((positionSwitch3 and 0x02) != 0x00) // 内升降槽型开关

    fun toJsonWithDly(): String {
        val json = JSONObject()
        json.put("macAddr", AppManager.MacAddress)
        json.put("nth", MOTOR_STATUS_LIST[innerPushMotor]) // 内推货电机
        json.put("bwm", MOTOR_STATUS_LIST[heatDoorMotor]) // 保温门
        json.put("wth", MOTOR_STATUS_LIST[externPushMotor]) // 外推货
        json.put("wsj", MOTOR_STATUS_LIST[externUpDownMotor]) // 外升降
        json.put("qwm", MOTOR_STATUS_LIST[pickDoorMotor]) // 取物门
        json.put("xz", MOTOR_STATUS_LIST[rotationMotor]) // 旋转电机
        json.put("nsj", MOTOR_STATUS_LIST[innerUpDownMotor]) // 内升降
        json.put("wbzt", waveStatus()) // 微波状态
        json.put("hwzt", irdaStatus()) // 红外状态
        json.put("dmzt", fridgeStatus()) // 大门
        json.put("xmzt", gateStatus()) // 小门
        json.put("gszt", rasterStatus()) // 光栅
        json.put("wdcgq", sensorStatus()) // 温度 传感器
        json.put("ps", ps)
        json.put("wdyc", tempValueError.toString()) // 温度异常
        json.put("trouble", isFault) // trouble
        json.put("machstatus", zt) // 总状态
        return json.toString()
    }

    fun waveStatus() = if (isWaveError()) "reveal" else "normal" // 微波状态
    fun irdaStatus() = if (isIrdaError()) "abnormal" else "normal" // 红外状态
    fun fridgeStatus() = if (isFridgeOpen()) "open" else "closed" // 大门
    fun gateStatus() = if (isGateOpen()) "open" else "closed" // 小门
    fun rasterStatus() = if (isRasterError()) "covered" else "nocovered" // 光栅
    fun sensorStatus() = SENSOR_STATUS_LIST[tempSensor]

    fun trouble() {
        var e = false
        val sb = StringBuilder()
        val keys = AppContext.resources.getStringArray(R.array.status_key)
        val values = AppContext.resources.getStringArray(R.array.status_val)

        if (innerPushMotor != 0x00) {
            e = true
            sb.append(keys[0]).append(":").append(values[innerPushMotor]).append("\r\n")
        }

        if (heatDoorMotor != 0x00) {
            e = true
            sb.append(keys[1]).append(":").append(values[heatDoorMotor]).append("\r\n")
        }

        if (externPushMotor != 0x00) {
            e = true
            sb.append(keys[2]).append(":").append(values[externPushMotor]).append("\r\n")
        }

        if (externUpDownMotor != 0x00) {
            e = true
            sb.append(keys[3]).append(":").append(values[externUpDownMotor]).append("\r\n")
        }

        if (pickDoorMotor != 0x00) {
            e = true
            sb.append(keys[4]).append(":").append(values[pickDoorMotor]).append("\r\n")
        }

        if (rotationMotor != 0x00) {
            e = true
            sb.append(keys[5]).append(":").append(values[rotationMotor]).append("\r\n")
        }

        if (innerUpDownMotor != 0x00) {
            e = true
            sb.append(keys[6]).append(":").append(values[innerUpDownMotor]).append("\r\n")
        }

        if (isWaveError()) {
            e = true
            sb.append(keys[7]).append(":").append("reveal").append("\r\n")
        }

        if (isIrdaError()) {
            e = true
            sb.append("Sensor infrared oven:abnormal\r\n")
        }

        if (isFridgeOpen()) {
            e = true
            sb.append("Front display panel door:open\r\n")
        }

        if (isGateOpen()) {
            e = true
            sb.append("Front door payment status:open\r\n")
        }

        if (isRasterError()) {
            e = true
            sb.append("Sensor delivery door:blocked\r\n")
        }

        if (tempSensor != 0x00) {
            e = true
            sb.append("Temperature sensor:abnormal\r\n")
        }

        if (tempValueError) {
            e = true
            sb.append("temperature anomaly\r\n")
        }
        if (ps != 0x00) {
            e = true
            sb.append("ps value is ${ps.toHex()}\r\n")
        }
        zt = if (e) {
            "malfunction"
        } else {
            "normal"
        }
        if (e) {
            sb.append("Service required TF - operator needed - Sorry for the inconvenience\r\n")
        }
        faultMessage = sb.toString()
        isFault = e
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is Status) return false

        if (innerPushMotor != other.innerPushMotor) return false
        if (heatDoorMotor != other.heatDoorMotor) return false
        if (externPushMotor != other.externPushMotor) return false
        if (externUpDownMotor != other.externUpDownMotor) return false
        if (pickDoorMotor != other.pickDoorMotor) return false
        if (rotationMotor != other.rotationMotor) return false
        if (innerUpDownMotor != other.innerUpDownMotor) return false
        if (tempSensor != other.tempSensor) return false
        if (isFridgeOpen() != other.isFridgeOpen()) return false
        if (isGateOpen() != other.isGateOpen()) return false
        if (isRasterError() != other.isRasterError()) return false
        if (isIrdaError() != other.isIrdaError()) return false
        if (isWaveError() != other.isWaveError()) return false
        if (tempValueError != other.tempValueError) return false // 温度异常
        if (ps != other.ps) return false

        return true
    }

    override fun hashCode(): Int {
        var result = innerPushMotor
        result = 31 * result + heatDoorMotor
        result = 31 * result + externPushMotor
        result = 31 * result + externUpDownMotor
        result = 31 * result + pickDoorMotor
        result = 31 * result + rotationMotor
        result = 31 * result + innerUpDownMotor
        result = 31 * result + tempSensor
        return result
    }

    fun toJson(): JSONObject {
        val json = JSONObject()
        json.put("content", byteArray.toHexString())
        return json
    }
}
